<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>代码重构的逻辑思路(Refactoring code)</title>
    <!-- 
  JavaScript代码重构是指对现有代码进行改进，以提高其可读性、可维护性和性能，而不改变其外部行为。
  代码重构是一个持续的过程，需要不断地审查和改进代码，以确保其质量。
  
    1. **明确重构目标**：
      - 确定重构的目的，例如提高代码可读性、减少重复代码、优化性能等。
      - 确保重构不会影响代码的功能和外部接口。

    2. **代码审查与分析**：
      - 对现有代码进行审查，识别出需要重构的部分。
      - 分析代码的结构、逻辑、复杂性和重复性，找出痛点。

    3. **模块化与分离关注点**：
      - 将大块代码拆分为小的、可重用的模块或函数。
      - 确保每个模块或函数关注单一职责，遵循单一职责原则（SRP）。

    4. **消除重复代码**：
      - 识别并消除重复的代码片段，提取公共逻辑到独立的函数或模块中。
      - 使用高阶函数、回调函数等实现代码复用。

    5. **命名规范**：
      - 使用清晰、描述性的命名来提高代码的可读性。
      - 变量、函数和类名应能准确传达其用途。

    6. **使用现代语法和特性**：
      - 利用ES6及以上版本的新特性，如箭头函数、解构赋值、模块导入导出等，提升代码简洁性和可读性。
      - 适当使用Promise、async/await等处理异步操作。

    7. **测试与验证**：
      - 在重构过程中，确保有足够的单元测试覆盖代码的功能。
      - 每次重构后运行测试，确保重构没有引入新的错误。

    8. **逐步重构**：
      - 逐步进行重构，而不是在一次性重构中进行大规模改动。
      - 小步前进，减少风险，便于发现和解决问题。

    9. **文档与注释**：
      - 更新相关文档和注释，以反映重构后的代码结构和逻辑。
      - 确保代码的可维护性和可理解性。

    总结：JS代码重构的逻辑思路包括明确重构目标、代码审查与分析、模块化、消除重复代码、使用现代语法、测试与验证、逐步重构，以及更新文档与注释。通过这些步骤，可以有效提高代码质量和可维护性。
  --></head>
  <body>
    <script>
      // 1.模块化与分离关注点: 将一个大型函数拆分为多个小函数，每个函数只负责一个特定的任务
      {
        // 重构前
        function processUserInput(input) {
          // 验证输入
          if (input === "") {
            return "输入不能为空";
          }
          // 处理输入
          return input.trim().toUpperCase();
        }

        // 重构后
        function processUserInputRefactoring(input) {
          const validation = validateInput(input);
          if (validation !== true) {
            return validation;
          }
          return processInput(input);
        }

        function validateInput(input) {
          if (input === "") {
            return "输入不能为空";
          }
          return true;
        }

        function processInput(input) {
          return input.trim().toUpperCase();
        }
      }

      // 2.消除重复代码: 找到重复的代码片段，并将其提取到单独的函数中
      {
        // 重构前
        function calculateTotalPrice(items) {
          let totalPrice = 0;
          for (let i = 0; i < items.length; i++) {
            totalPrice += items[i].price * items[i].quantity;
          }
          return totalPrice;
        }

        function calculateDiscountedPrice(items) {
          let discountedPrice = 0;
          for (let i = 0; i < items.length; i++) {
            discountedPrice += items[i].price * items[i].quantity;
          }
          return discountedPrice;
        }

        // 重构后
        function calculateTotalPriceRefactoring(items) {
          return calculateTotal(items);
        }

        function calculateTotal(items) {
          let total = 0;
          for (let i = 0; i < items.length; i++) {
            total += items[i].price * items[i].quantity;
          }
          return total;
        }

        function calculateDiscountedPrice(items) {
          return calculateTotal(items);
        }
        // --------------------------------------------------
        // 重复代码
        function uniqueArray(arr) {
          return Array.from(new Set(arr));
        }

        // 使用公共函数
        const arr1 = uniqueArray([1, 2, 2, 3]);
        const arr2 = uniqueArray([4, 5, 5, 6]);
      }

      // 3. 使用现代语法和特性 - 使用箭头函数和解构赋值来简化代码
      {
        // 重构前
        function add(x, y) {
          return x + y;
        }

        // 重构后
        const add = (x, y) => x + y;
      }

      // 4. 使用设计模式 - 使用观察者模式来处理事件
      {
        // 重构前
        function on(event, callback) {
          // 事件处理逻辑
        }

        function off(event, callback) {
          // 事件处理逻辑
        }

        function trigger(event, data) {
          // 事件处理逻辑
        }

        // 重构后
        class EventEmitter {
          constructor() {
            this.events = {};
          }

          on(event, callback) {
            if (!this.events[event]) {
              this.events[event] = [];
            }
            this.events[event].push(callback);
          }

          off(event, callback) {
            if (this.events[event]) {
              this.events[event] = this.events[event].filter(
                (cb) => cb !== callback
              );
            }
          }

          trigger(event, data) {
            if (this.events[event]) {
              this.events[event].forEach((cb) => cb(data));
            }
          }
        }
      }
    
      // 5. 使用设计模式 - 使用工厂模式来创建对象
      {
        // 重构前
        function createCar(model, year, miles) {
          const car = {};
          car.model = model;
          car.year = year;
          car.miles = miles;
          car.toString = function () {
            return `${this.model} has done ${this.miles} miles.`;
          };
          return car;
        }

        const civic1 = createCar("Honda Civic", 2009, 20000);
        const mondeo1 = createCar("Ford Mondeo", 2010, 5000);

        // 重构后
        function Car(options) {
          this.model = options.model || "unknown";
          this.year = options.year || new Date().getFullYear();
          this.miles = options.miles || 0;
        }

        Car.prototype.toString = function () {
          return `${this.model} has done ${this.miles} miles.`;
        };

        const civic2 = new Car({ model: "Honda Civic", year: 2009, miles: 20000 });
        const mondeo2 = new Car({ model: "Ford Mondeo", year: 2010, miles: 5000 });
      }

      // 6.文档与注释 - 重构后更新代码注释，确保它们描述新的逻辑和结构
      {
        /**
         * 处理用户输入
         * @param {string} input - 用户输入
         * @returns {string} - 处理后的输入
         */
        function processUserInput(input) {
            // ...
        }
      }
    </script>
  </body>
</html>
